package com.ungao.tools.generator.engine;

import com.ungao.tools.generator.engine.config.TemplateConfig;
import freemarker.template.Configuration;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Map;

public class FreemarkerTemplateEngine extends AbstractTemplateEngine {
    private final Configuration configuration;

    public FreemarkerTemplateEngine() {
        this.configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
        this.configuration.setDefaultEncoding(super.defaultCharset);
        this.configuration.setClassForTemplateLoading(FreemarkerTemplateEngine.class, super.defaultTemplatePath);
    }

    @Override
    public FreemarkerTemplateEngine init(TemplateConfig configBuilder) throws Exception {
        super.init(configBuilder);
        if (configBuilder.getTemplatePath() != null && configBuilder.getTemplatePath() != "") {
            this.configuration.setClassForTemplateLoading(FreemarkerTemplateEngine.class, configBuilder.getTemplatePath());
        }
        return this;
    }

    @Override
    public void writer(String templatePath, String targetPath) throws Exception {
        this.writer(super.config, templatePath, targetPath);
    }

    @Override
    public <T> void writer(T model, String templatePath, String targetPath) throws Exception {
        Map<String, Object> resource = new HashMap<>(super.config);
        resource.putIfAbsent("info", model);
        this.writer(resource, templatePath, targetPath);
    }

    @Override
    public void writer(Map<String, Object> resource, String templatePath, String targetPath) throws Exception {
        try (FileOutputStream fos = new FileOutputStream(targetPath);
             OutputStreamWriter osw = new OutputStreamWriter(fos, super.defaultCharset);
             BufferedWriter writer = new BufferedWriter(osw, 1024)) {
            this.configuration.getTemplate(templatePath).process(resource, writer);
        } catch (Exception e) {
            throw e;
        }
    }

    @Override
    public String templateFilePath(String filePath) {
        return filePath + ".ftl";
    }
}
